AI Agent with charts capabilities using OpenAI Structured Output
工作流概述
这是一个包含11个节点的复杂工作流,主要用于自动化处理各种任务。
工作流源代码
{
"id": "6yNJxDjV9rSiOkj9",
"meta": {
"instanceId": "f4f5d195bb2162a0972f737368404b18be694648d365d6c6771d7b4909d28167",
"templateCredsSetupCompleted": true
},
"name": "AI Agent with charts capabilities using OpenAI Structured Output",
"tags": [
{
"id": "9tRfTc35T5pruw03",
"name": "experiment",
"createdAt": "2024-03-18T15:32:10.504Z",
"updatedAt": "2024-03-18T15:32:10.504Z"
}
],
"nodes": [
{
"id": "4b7c314a-d7c5-46cb-af6f-b3ff02a182b7",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
980,
600
],
"parameters": {
"model": "gpt-4o-mini-2024-07-18",
"options": {}
},
"credentials": {
"openAiApi": {
"id": "WqzqjezKh8VtxdqA",
"name": "OpenAi account - Baptiste"
}
},
"typeVersion": 1
},
{
"id": "cf4ffa49-8830-4db2-9a7d-b8931e806947",
"name": "Window Buffer Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
1120,
600
],
"parameters": {},
"typeVersion": 1.2
},
{
"id": "22d36226-ca37-4ccc-a2d6-826b78c2f1f3",
"name": "Generate a chart",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
1260,
600
],
"parameters": {
"name": "generate_a_chart",
"schemaType": "manual",
"workflowId": "={{ $workflow.id }}",
"description": "Call this tool whenever you need to generate a chart.",
"inputSchema": "{
\"type\": \"object\",
\"properties\": {
\"query\": {
\"type\": \"string\",
\"description\": \"a query describing the chart to generate\"
}
}
}",
"specifyInputSchema": true
},
"typeVersion": 1.1
},
{
"id": "d9ea85d7-3a56-4a95-88c8-60e5c95014e7",
"name": "Execute \"Generate a chart\" tool",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
580,
1100
],
"parameters": {},
"typeVersion": 1
},
{
"id": "68d538f7-acce-447f-9ab1-6975639e05f7",
"name": "OpenAI - Generate Chart definition with Structured Output",
"type": "n8n-nodes-base.httpRequest",
"position": [
880,
1100
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"method": "POST",
"options": {},
"jsonBody": "={
\"model\": \"gpt-4o-2024-08-06\",
\"messages\": [
{
\"role\": \"system\",
\"content\": \"Based on the user request, generate a valid Chart.js definition. Important: - Be careful with the data scale and beginatzero that all data are visible. Example if ploted data 2 and 3 on a bar chart, the baseline should be 0. - Charts colors should be different only if there are multiple datasets. - Output valid JSON. In scales, min and max are numbers. Example: `{scales:{yAxes:[{ticks:{min:0,max:3}`\"
},
{
\"role\": \"user\",
\"content\": \"{{ $json.query.query }}\"
}
],
\"response_format\": {
\"type\": \"json_schema\",
\"json_schema\": {
\"name\": \"chart_configuration\",
\"description\": \"Configuration schema for Chart.js charts\",
\"strict\": true,
\"schema\": {
\"type\": \"object\",
\"properties\": {
\"type\": {
\"type\": \"string\",
\"enum\": [\"bar\", \"line\", \"radar\", \"pie\", \"doughnut\", \"polarArea\", \"bubble\", \"scatter\", \"area\"]
},
\"data\": {
\"type\": \"object\",
\"properties\": {
\"labels\": {
\"type\": \"array\",
\"items\": {
\"type\": \"string\"
}
},
\"datasets\": {
\"type\": \"array\",
\"items\": {
\"type\": \"object\",
\"properties\": {
\"label\": {
\"type\": [\"string\", \"null\"]
},
\"data\": {
\"type\": \"array\",
\"items\": {
\"type\": \"number\"
}
},
\"backgroundColor\": {
\"type\": [\"array\", \"null\"],
\"items\": {
\"type\": \"string\"
}
},
\"borderColor\": {
\"type\": [\"array\", \"null\"],
\"items\": {
\"type\": \"string\"
}
},
\"borderWidth\": {
\"type\": [\"number\", \"null\"]
}
},
\"required\": [\"data\", \"label\", \"backgroundColor\", \"borderColor\", \"borderWidth\"],
\"additionalProperties\": false
}
}
},
\"required\": [\"labels\", \"datasets\"],
\"additionalProperties\": false
},
\"options\": {
\"type\": \"object\",
\"properties\": {
\"scales\": {
\"type\": [\"object\", \"null\"],
\"properties\": {
\"yAxes\": {
\"type\": \"array\",
\"items\": {
\"type\": [\"object\", \"null\"],
\"properties\": {
\"ticks\": {
\"type\": [\"object\", \"null\"],
\"properties\": {
\"max\": {
\"type\": [\"number\", \"null\"]
},
\"min\": {
\"type\": [\"number\", \"null\"]
},
\"stepSize\": {
\"type\": [\"number\", \"null\"]
},
\"beginAtZero\": {
\"type\": [\"boolean\", \"null\"]
}
},
\"required\": [\"max\", \"min\", \"stepSize\", \"beginAtZero\"],
\"additionalProperties\": false
},
\"stacked\": {
\"type\": [\"boolean\", \"null\"]
}
},
\"required\": [\"ticks\", \"stacked\"],
\"additionalProperties\": false
}},
\"xAxes\": {
\"type\": [\"object\", \"null\"],
\"properties\": {
\"stacked\": {
\"type\": [\"boolean\", \"null\"]
}
},
\"required\": [\"stacked\"],
\"additionalProperties\": false
}
},
\"required\": [\"yAxes\", \"xAxes\"],
\"additionalProperties\": false
},
\"plugins\": {
\"type\": [\"object\", \"null\"],
\"properties\": {
\"title\": {
\"type\": [\"object\", \"null\"],
\"properties\": {
\"display\": {
\"type\": [\"boolean\", \"null\"]
},
\"text\": {
\"type\": [\"string\", \"null\"]
}
},
\"required\": [\"display\", \"text\"],
\"additionalProperties\": false
},
\"legend\": {
\"type\": [\"object\", \"null\"],
\"properties\": {
\"display\": {
\"type\": [\"boolean\", \"null\"]
},
\"position\": {
\"type\": [\"string\", \"null\"],
\"enum\": [\"top\", \"left\", \"bottom\", \"right\", null]
}
},
\"required\": [\"display\", \"position\"],
\"additionalProperties\": false
}
},
\"required\": [\"title\", \"legend\"],
\"additionalProperties\": false
}
},
\"required\": [\"scales\", \"plugins\"],
\"additionalProperties\": false
}
},
\"required\": [\"type\", \"data\", \"options\"],
\"additionalProperties\": false
}
}
}
}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "=Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "openAiApi"
},
"credentials": {
"openAiApi": {
"id": "WqzqjezKh8VtxdqA",
"name": "OpenAi account - Baptiste"
}
},
"typeVersion": 4.2
},
{
"id": "0fd4ad08-ad85-4d0b-b75f-0e59f789cbfd",
"name": "Set response",
"type": "n8n-nodes-base.set",
"position": [
1120,
1100
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "37512e1a-8376-4ba0-bdcd-34bb9329ae4b",
"name": "response",
"type": "string",
"value": "={{ encodeURIComponent(\"https://quickchart.io/chart?width=200&c=\"+$json.choices[0].message.content) }}
"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6785cadb-4875-47ac-9b57-29b583c53937",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
20,
260
],
"parameters": {
"color": 7,
"width": 680.7609104727082,
"height": 619.3187860363884,
"content": "## Workflow: AI Agent with charts capabilities using OpenAI Structured Output
**Overview**
- This workflow is a experiment to integrate charts into an AI Agent
- The AI Agent has normal AI conversation and can invoke a tool to integrate a graph in the conversation.
- It uses OpenAI Structured Output to generate a chart definition according to Quickchart specifications.
**How it works**
- Activate the workflow
- Start chatting with the AI Agent.
- When the AI Agent detects that the user needs a chat, it calls the tool
- The tool calls the sub-workflow with a query.
- The sub-workflow calls the HTTP Request node (calling OpenAI) to retrieve a chart definition
- In the \"set response\" node, he chat definition is added at the end of a quickchart.io url - the URL to the chart image. It is sent back to the AI Agent.
- The AI Agent uses this image in its response.
- For example, you can ask the AI Agent to generate a chart about the top 5 movies at the box office
**Notes**
- The full Quickchart.io specifications have not been integrated, thus there are some possible glitches (e.g due to the size of the graph, radar graphs are not displayed properly)
- This could be provided to any automation, not only AI Agents."
},
"typeVersion": 1
},
{
"id": "fd507ff6-2d16-4498-ba2b-d91b02079311",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
740,
800
],
"parameters": {
"color": 7,
"width": 768.8586342909368,
"height": 503,
"content": "## Generate a Quickchart definition
**HTTP Request node**
- Send the chart query to OpenAI, with a defined JSON response format - *using HTTP Request node as it has not yet been implemented in the OpenAI nodes*
- The JSON structure is based on ChartJS and Quickchart.io definitions, that let us create nice looking graphs.
- The output is a JSON containing the chart definition that is passed to the next node.
**Set Response node**
- Adds the chart definition at the end of a Quickchart.io URL ([see documentation](https://quickchart.io/documentation/usage/parameters/))
- Note that in the parameters, we specify the width to 250 in order to be properly displayed in the chart interface."
},
"typeVersion": 1
},
{
"id": "7f14532a-75ee-40f8-a45b-0f037af7cb05",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
740,
260
],
"parameters": {
"color": 7,
"width": 768,
"height": 485.8165429718969,
"content": "### Chat Agent
- This is agent is mostly here to demonstrate how to use the sub workflow.
- This is a basic agent with a tool \"generate a chart\"
- The tool calls the sub-workflow
- The sub-workflow responds with the Quickchart URL that is displayed in the conversation"
},
"typeVersion": 1
},
{
"id": "7793a567-c4d4-4745-83c9-adf5397755e9",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1020,
400
],
"parameters": {
"options": {
"systemMessage": "You're a general purpose ai. Using markdown, you can display images in the conversation. Don't change the width of the chart"
}
},
"typeVersion": 1.6
},
{
"id": "71bd2cb5-7b20-4d83-adba-c1fd57511155",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
840,
400
],
"webhookId": "1281cd48-08a0-431d-9bf5-9bb60e6b7a77",
"parameters": {
"options": {}
},
"typeVersion": 1.1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "3af7cf64-60dc-4ba6-9ac6-f7ed2453812c",
"connections": {
"Generate a chart": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Window Buffer Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Execute \"Generate a chart\" tool": {
"main": [
[
{
"node": "OpenAI - Generate Chart definition with Structured Output",
"type": "main",
"index": 0
}
]
]
},
"OpenAI - Generate Chart definition with Structured Output": {
"main": [
[
{
"node": "Set response",
"type": "main",
"index": 0
}
]
]
}
}
}
功能特点
- 自动检测新邮件
- AI智能内容分析
- 自定义分类规则
- 批量处理能力
- 详细的处理日志
技术分析
节点类型及作用
- @N8N/N8N Nodes Langchain.Lmchatopenai
- @N8N/N8N Nodes Langchain.Memorybufferwindow
- @N8N/N8N Nodes Langchain.Toolworkflow
- Executeworkflowtrigger
- Httprequest
复杂度评估
配置难度:
维护难度:
扩展性:
实施指南
前置条件
- 有效的Gmail账户
- n8n平台访问权限
- Google API凭证
- AI分类服务订阅
配置步骤
- 在n8n中导入工作流JSON文件
- 配置Gmail节点的认证信息
- 设置AI分类器的API密钥
- 自定义分类规则和标签映射
- 测试工作流执行
- 配置定时触发器(可选)
关键参数
| 参数名称 | 默认值 | 说明 |
|---|---|---|
| maxEmails | 50 | 单次处理的最大邮件数量 |
| confidenceThreshold | 0.8 | 分类置信度阈值 |
| autoLabel | true | 是否自动添加标签 |
最佳实践
优化建议
- 定期更新AI分类模型以提高准确性
- 根据邮件量调整处理批次大小
- 设置合理的分类置信度阈值
- 定期清理过期的分类规则
安全注意事项
- 妥善保管API密钥和认证信息
- 限制工作流的访问权限
- 定期审查处理日志
- 启用双因素认证保护Gmail账户
性能优化
- 使用增量处理减少重复工作
- 缓存频繁访问的数据
- 并行处理多个邮件分类任务
- 监控系统资源使用情况
故障排除
常见问题
邮件未被正确分类
检查AI分类器的置信度阈值设置,适当降低阈值或更新训练数据。
Gmail认证失败
确认Google API凭证有效且具有正确的权限范围,重新进行OAuth授权。
调试技巧
- 启用详细日志记录查看每个步骤的执行情况
- 使用测试邮件验证分类逻辑
- 检查网络连接和API服务状态
- 逐步执行工作流定位问题节点
错误处理
工作流包含以下错误处理机制:
- 网络超时自动重试(最多3次)
- API错误记录和告警
- 处理失败邮件的隔离机制
- 异常情况下的回滚操作